<!-- 聊天备份 -->
<template>
  <div class="dashboard-editor-container">
    <el-row style="background: #fff; ">
      <div class="xxx" style="display:flex;justify-content:space-between;">
        <div class="lefttree" style="height:calc(100vh - 70px);" v-show="tab1">
          <!-- <div class="tabclick">
          <div class="tabitem" @click="handleClick2()">
            <span><i :class="tab1 ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i></span>
          </div>
        </div> -->
          <!-- icon-class="el-icon-arrow-right"  -->
          <el-tree ref="tree" node-key="id" :data="CustomerList" :expand-on-click-node=false :props="defaultProps"
            @node-click="handleNodeClick" :default-expanded-keys="defaultDeployment" highlight-current
            style="width:230px;">
            <span slot-scope="{ node, data }" class="custom-tree-node">
              <span style="display:flex;align-items:center;">
                <svg-icon v-show="node.level === 1" icon-class="peoples" style="margin-right: 10px;font-size:14px;" />
                <svg-icon v-show="node.level === 2" icon-class="user" style="margin-right: 10px;font-size:14px;" />
                <svg-icon v-show="node.level === 3 && node.label === 'WX'" icon-class="wechat"
                  style="margin-right: 10px;font-size:14px;" />
                <svg-icon v-show="node.level === 3 && node.label === 'QQ'" icon-class="qq" style="margin-right: 10px;font-size:14px;" />
                <svg-icon v-show="node.level === 4" icon-class="message" style="margin-right: 10px;font-size:14px;" />
                <el-tooltip v-if="node.level > 4" class="item" effect="dark" :content="`${node.label}（${data.Count}）`"
                  placement="right">
                  <span class="tree-text">{{ node.label }}（{{ data.Count }}）</span>
                </el-tooltip>
                <span v-else class="tree-text">{{ node.label }}</span>
              </span>
            </span>
          </el-tree>
          <!-- :render-content="renderContent" -->
        </div>
        <div style="width:calc(100% - 290px)">
          <connsearch ref="connsearch" :formOptions="formOptions" @search="search" @reset="reset" />
          <div class="tabclick">
            <div class="tabitem" @click="handleClick()">
              <span><i :class="tab ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i></span>
              <!-- <img v-if="tab" src="../../assets//down.png" alt=""> -->
              <!-- <img v-if="!tab" src="../../assets//up.png" alt=""> -->
            </div>
          </div>
          <el-row>
            <el-tabs type="border-card" v-if="tab" style="margin-top:16px;" @tab-click="tabClick">
              <el-tab-pane label="按日统计分析" lazy>
                <el-col :xs="24" :sm="24" :lg="24">
                  <barchart :title="'按日统计分析'" :chartData="barchartData" @barclick="echartsClick" />
                </el-col>
              </el-tab-pane>
              <el-tab-pane label="按资产统计分析" lazy>
                <el-row :gutter="20">
                  <el-col :xs="24" :sm="24" :lg="24">
                    <piechart :title="'按资产统计分析'" :chartData="pie1Data" @pieclick="echartsClick" />
                  </el-col>
                </el-row>
              </el-tab-pane>
              <el-tab-pane label="按聊天工具分类统计" lazy>
                <el-col :xs="24" :sm="24" :lg="24">
                  <piechart :title="'按聊天工具分类统计'" :chartData="pie2Data" @pieclick="echartsClick" />
                </el-col>
              </el-tab-pane>
              <el-tab-pane label="按聊天对象分类统计" lazy>
                <el-col :xs="24" :sm="24" :lg="24">
                  <piechart :title="'按聊天对象分类统计'" :chartData="pie3Data" @pieclick="echartsClick" />
                </el-col>
              </el-tab-pane>
            </el-tabs>
          </el-row>
          <el-tabs type="border-card" v-show="level === 5" @tab-click="level5Click">
            <el-tab-pane label="看板模式">
              <el-col :xs="{ span: 24 }" :sm="{ span: 24 }" :md="{ span: 24 }" :lg="{ span: 24 }" :xl="{ span: 24 }"
                style="padding-right: 8px;margin: 16px 0;">
                <div class="chat-messages zoom-div" ref="chatMessages" @mousewheel="handleScroll">
                  <el-tooltip class="item" effect="dark" content="全屏" placement="top">
                    <i v-show="zoom" class=" zoom el-icon-full-screen" @click="zoomIn"></i>
                  </el-tooltip>
                  <el-tooltip class="item" effect="dark" content="退出全屏" placement="top">
                    <i v-show="!zoom" class=" zoom el-icon-switch-button" @click="zoomOut" ref="zoomOut"></i>
                  </el-tooltip>
                  <div style="text-align:center"><el-link type="primary" :underline="false" @click="callApi()"
                      v-show="!islast">查看更多消息</el-link></div>
                  <div style="text-align:center"><el-link type="info" :underline="false" v-show="islast">没有更多消息</el-link>
                  </div>
                  <div v-for="(message, index) in MessagesList" :key="index"
                    :class="{ 'chat-message-left': message.IsSend === 0, 'chat-message-right': message.IsSend === 1 }">
                    <div class="chat-avatar">
                      <img v-if="message.IsSend === 0" src="../../assets/avatar2.jpg" alt="">
                    </div>
                    <div class="chat-content">
                      <div style="display:flex;justify-content: space-between;color:#ccc;">
                        <span class="chat-time" v-show="message.IsSend === 0">{{ message.SenderNickName }}</span>
                        <span class="chat-time">{{ message.TransTime }}</span>
                        <span class="chat-time" v-show="message.IsSend === 1">{{ message.SenderNickName }}</span>
                      </div>
                      <span style="white-space: pre-line" v-html="message.Content" class="chat-message-text"></span>
                    </div>
                    <div class="chat-avatar">
                      <img v-if="message.IsSend === 1" src="../../assets/avatar3.jpg" alt="">
                    </div>
                  </div>
                </div>
              </el-col>
            </el-tab-pane>
            <el-tab-pane label="列表模式">
              <el-col :xs="{ span: 24 }" :sm="{ span: 24 }" :md="{ span: 24 }" :lg="{ span: 24 }" :xl="{ span: 24 }"
                style="padding-right: 8px;">
                <!-- <span class="title">聊天备份列表</span> -->
                <el-table stripe border :data="tableData" height="500px" style="width: 100%; margin-top: 15px">
                  <el-table-column label="序号" width="60" type="index"
                    :index='(index) => { return (index + 1) + (this.pageNum - 1) * this.pageSize }'> </el-table-column>
                  <el-table-column label="聊天时间" prop="TransTime" width="160px"></el-table-column>
                  <el-table-column label="聊天终端" prop="DeviceName" width="180px" show-overflow-tooltip>
                    <template slot-scope="{ row }">
                      <div class="name">{{ row.DeviceName }}（{{ row.Department }}）</div>
                    </template>
                  </el-table-column>
                  <!-- <el-table-column label="聊天工具" prop="IMTool"  width="80px" show-overflow-tooltip>
                
              </el-table-column> -->
                  <!-- <el-table-column label="消息类型" prop="MsgSubType"  width="80px">
                <template slot-scope="{ row }">
                  <div class="name">{{ row.MsgSubType === 'Buddy' ? '私聊' : '群聊'}}</div>
                </template>
              </el-table-column> -->
                  <el-table-column label="发送账号" prop="SenderNickName" width="200px" show-overflow-tooltip>
                    <template slot-scope="{ row }">
                      <span class="showOverflowTooltip">{{ row.SenderNickName }}（{{ row.SenderAccount }}）</span>
                    </template>
                  </el-table-column>
                  <el-table-column label="聊天方向" prop="IsSend" width="80px">
                    <template slot-scope="{ row }">
                      <div class="name" :style="{ color: row.IsSend === 1 ? '#67C23A' : '#F56C6C' }">{{ row.IsSend === 1 ?
                        '发送' : '接收' }}
                        <i v-show="row.IsSend === 1" style="color:#67C23A" class="el-icon-right"></i>
                        <i v-show="row.IsSend !== 1" style="color:#F56C6C" class="el-icon-back"></i>
                      </div>
                    </template>
                  </el-table-column>
                  <el-table-column label="接收账号" prop="PeerNickName" width="200px" show-overflow-tooltip>
                    <template slot-scope="{ row }">
                      <div class="showOverflowTooltip">{{ row.PeerNickName }}（{{ row.PeerAccount }}）</div>
                    </template>
                    <!-- PeerAccount -->
                  </el-table-column>
                  <el-table-column label="聊天内容" prop="Content" show-overflow-tooltip></el-table-column>
                  <el-table-column label="操作" width="80px">
                    <template slot-scope="scope">
                      <el-button size="mini" type="danger" @click="handleDelete(scope.row)">删除</el-button>
                    </template>
                  </el-table-column>
                </el-table>
                <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page=pageNum
                  :page-size=pageSize background layout="total, prev, pager, sizes, next, jumper" :total="total">
                </el-pagination>
              </el-col>
            </el-tab-pane>
          </el-tabs>
          <!-- <el-row v-show="level === 5" style="border:1px solid #ccc; border-bottom:none;">
        <div class="tab">
          <span :class="mode === 'chat' ? 'tabButton tabButtonActive' : 'tabButton' " @click="changeMode('chat')">看板模式</span>
          <span :class="mode === 'table' ? 'tabButton tabButtonActive' : 'tabButton' " @click="changeMode('table')">列表模式</span>
        </div>
      </el-row> -->
          <el-col :xs="{ span: 24 }" :sm="{ span: 24 }" :md="{ span: 24 }" :lg="{ span: 24 }" :xl="{ span: 24 }"
            style="padding-right: 8px;margin: 16px 0;" v-show="mode === 'table' && level !== 5">
            <!-- <span class="title">聊天备份列表</span> -->
            <el-table stripe border :data="tableData" style="width: 100%; margin-top: 15px">
              <el-table-column label="序号" width="60" type="index"
                :index='(index) => { return (index + 1) + (this.pageNum - 1) * this.pageSize }'> </el-table-column>
              <el-table-column label="聊天时间" prop="TransTime" width="160px"></el-table-column>
              <el-table-column label="聊天终端" prop="DeviceName" width="180px" show-overflow-tooltip>
                <template slot-scope="{ row }">
                  <div class="name">{{ row.DeviceName }}（{{ row.Department }}）</div>
                </template>
              </el-table-column>
              <!-- <el-table-column label="聊天工具" prop="IMTool"  width="80px" show-overflow-tooltip>
          </el-table-column> -->
              <!-- <el-table-column label="消息类型" prop="MsgSubType"  width="80px">
            <template slot-scope="{ row }">
              <div class="name">{{ row.MsgSubType === 'Buddy' ? '私聊' : '群聊'}}</div>
            </template>
          </el-table-column> -->
              <el-table-column label="发送账号" prop="SenderNickName" width="200px" show-overflow-tooltip>
                <template slot-scope="{ row }">
                  <div class="showOverflowTooltip">{{ row.SenderNickName }}（{{ row.SenderAccount }}）</div>
                </template>
              </el-table-column>
              <el-table-column label="聊天方向" prop="IsSend" width="80px">
                <template slot-scope="{ row }">
                  <div class="name" :style="{ color: row.IsSend === 1 ? '#67C23A' : '#F56C6C' }">{{ row.IsSend === 1 ?
                    '发送'
                    : '接收' }}
                    <i v-show="row.IsSend === 1" style="color:#67C23A" class="el-icon-right"></i>
                    <i v-show="row.IsSend !== 1" style="color:#F56C6C" class="el-icon-back"></i>
                  </div>
                </template>
              </el-table-column>
              <el-table-column label="接收账号" prop="PeerNickName" width="200px" show-overflow-tooltip>
                <template slot-scope="{ row }">
                  <div class="showOverflowTooltip">{{ row.PeerNickName }}（{{ row.PeerAccount }}）</div>
                </template>
                <!-- PeerAccount -->
              </el-table-column>
              <el-table-column label="聊天内容" prop="Content" show-overflow-tooltip></el-table-column>
              <el-table-column label="操作" width="80px">
                <template slot-scope="scope">
                  <el-button size="mini" type="danger" @click="handleDelete(scope.row)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
            <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page=pageNum
              :page-size=pageSize background layout="total, prev, pager, sizes, next, jumper" :total="total">
            </el-pagination>
          </el-col>
        </div>
      </div>
    </el-row>
  </div>
</template>

<script>
// 节流函数
function throttle(func, delay) {
  let timeoutId;
  return function () {
    if (!timeoutId) {
      // 设置延迟执行
      timeoutId = setTimeout(() => {
        func.apply(this, arguments);
        timeoutId = null;
      }, delay);
    }
  };
}
import Cookies from 'js-cookie'
import { parseTime} from '@/utils/index.js';
import { connrequest } from '@/api/firstPage.js';
import connsearch from "@/components/connSearch";
import barchart from "./components/barchart2.vue";
import piechart from "./components/piechart.vue";
export default {
  components: { connsearch, barchart, piechart },
  data() {
    let that = this
    return {
      zoom: true,
      seeMore: false,
      activeName: '按日统计',
      tabTitle: '按日统计分析',
      ChatTabTitle: '列表模式',
      tableData: [],
      devices: [],
      choseNode: {},
      mode: 'table',
      pageNum: 1,
      pageSize: 10,
      total: 0,
      level: 0,
      tab: false,
      tab1: true,
      islast: false,
      CustomerList: [],
      MessagesList: [],
      onNodeClick: {},
      defaultDeployment: [],
      tab2: false,
      barchartData: { xAxis: [], series: [] },
      pie1Data: [],
      pie2Data: [],
      pie3Data: [],
      searchform: {},
      searchobj: {},
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      formOptions: [
        {
          col: 12,
          label: "日期",
          prop: "timeRange",
          element: "el-date-picker",
          initValue: [],
          type: "",
          events: {
            input(val) {
              that.searchform.timeRange = val
            },
          },
        },
        {
          col: 12,
          label: "聊天内容",
          prop: "Descp",
          element: "el-input",
          placeholder: "请输入聊天内容,支持模糊查询。",
          events: {
            input(val) {
              that.searchform.Descp = val
            },
          },
        },
      ]
    };
  },
  //生命周期 - 创建完成（访问当前this实例）
  created() {
    this.pageSize = (Cookies.get('Zhuoguan_DefaultPageLength') || 10) * 1;

    let endTime = new Date(new Date().setHours(0, 0, 0, 0)).getTime()
    let startTime = endTime - ((Cookies.get('Zhuoguan_DefaultLogDays') || 7) * 24 * 3600 * 1000);
    let arr = [parseTime(startTime), '']
    this.formOptions.map(item => {
      if (item.label === '日期') {
        item.initValue = arr
      }
    })
    this.$set(this.searchform, 'timeRange', arr)
    this.getData()
    this.organizationStructure()
    this.getDevice()
    // 创建节流后的callApi方法
    this.throttledCallApi = throttle(this.callApi, 1000); // 1000毫秒为节流延迟时间
  },
  //生命周期 - 挂载完成（访问DOM元素）
  mounted() {
    this.$refs.chatMessages.addEventListener('scroll', this.handleScroll);
  },
  methods: {
    zoomIn() {
      this.zoom = !this.zoom
      // 获取div的引用
      const div = this.$refs.chatMessages;
      // 修改div的样式
      div.style.width = 'calc(100vw - 210px)';
      div.style.height = 'calc(100vh - 50px)';
      div.style.position = 'fixed';
      div.style.left = '210px';
      div.style.top = '50px';
      div.style.zIndex = '9';
      const div2 = this.$refs.zoomOut;
      div2.style.bottom = '20px';
      div2.style.right = '70px';
      div2.style.zIndex = '99999';
    },
    zoomOut() {
      this.zoom = !this.zoom
      // 获取div的引用
      const div = this.$refs.chatMessages;
      // 修改div的样式
      div.style.width = '100%';
      div.style.height = 'calc(100vh - 320px)';
      div.style.position = 'static';
    },
    async getDevice(){
      const data = {
        Paging: {
          QueryPageNo: 1,
          QueryPageLength: 100000
        },
      }
      const res = await connrequest('GetDevice', data)
      this.devices = res.Data
    },
    getData(searchobj = {}) {
      this.GetIMChatLog(searchobj)
      switch (this.tabTitle) {
        case '按日统计分析':
          this.GetIMChatSumByDate(searchobj)
          break;
        case '按资产统计分析':
          this.GetIMChatSumByUser(searchobj)
          break;
        case '按聊天工具分类统计':
          this.GetIMChatSumByIMTool(searchobj)
          break;
        default:
          this.GetIMChatSumByAccount(searchobj)
          break;
      }
    },
    tabClick(row) {
      this.tabTitle = row.label
      switch (this.tabTitle) {
        case '按日统计分析':
          this.GetIMChatSumByDate({ ...this.searchobj})
          break;
        case '按资产统计分析':
          this.GetIMChatSumByUser({ ...this.searchobj})
          break;
        case '按聊天工具分类统计':
          this.GetIMChatSumByIMTool({ ...this.searchobj})
          break;
        default:
          this.GetIMChatSumByAccount({ ...this.searchobj})
          break;
      }
    },
    handleDelete(row) {
      this.$confirm('数据删除后将不可恢复，确认要删除吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        const data = {
          Data: {
            AutoID: row.AutoID
          }
        }
        const res = await connrequest('DeleteIMChatLog', data)
        if (res.Status.StatusCode === 0) {
          this.$message({
            type: 'success',
            message: '删除成功!'
          });
          this.getData({ ...this.searchobj})
          // this.deleteClick = true
          this.handleNodeClick(this.onNodeClick.item, this.onNodeClick.node, this.pageNum)
        }
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    async handleNodeClick(item, node) {
      this.searchobj = {
        DepartmentID: item.DepartmentID,
        DeviceUUID: node.level > 1 ? item.DeviceUUID : undefined,
      }
      this.mode = 'table'
      this.pageNum = 1
      this.level = node.level
      this.islast = false
      this.onNodeClick = { item, node }
      let obj = {}
      if (node.level === 5) {
        // this.mode = this.deleteClick === true ? 'table' : 'chat'
        this.MessagesList = []
        let MsgSubType = ''
        if (node.parent.parent.data.label === 'WX') {
          MsgSubType = node.parent.label === '私聊' ? 'Buddy' : node.parent.label === '群聊' ? 'Group' : 'official'
        } else {
          MsgSubType = node.parent.label === '私聊' ? 'Buddy' : node.parent.label === '群聊' ? 'Group' : 'discuss'
        }
        obj = {
          Account: item.label,
          MsgSubType: MsgSubType,
          IMTool: node.parent.parent.data.label,
          DepartmentID: item.DepartmentID,
          DeviceUUID: item.DeviceUUID,
          Name: node.parent.parent.parent.data.label
        }
        this.$nextTick(() => {
          this.level5Click({ label: '看板模式' })
        })
      }
      if (node.level === 4) {
        let MsgSubType = ''
        if (node.parent.data.label === 'WX') {
          MsgSubType = item.label === '私聊' ? 'Buddy' : item.label === '群聊' ? 'Group' : 'official'
        } else {
          MsgSubType = item.label === '私聊' ? 'Buddy' : item.label === '群聊' ? 'Group' : 'discuss'
        }
        obj = {
          MsgSubType: MsgSubType,
          IMTool: node.parent.data.label,
          DepartmentID: item.DepartmentID,
          DeviceUUID: item.DeviceUUID,
          Name: node.parent.parent.data.label
        }
      } else if (node.level === 3) {
        obj = {
          IMTool: item.label,
          DepartmentID: item.DepartmentID,
          DeviceUUID: item.DeviceUUID,
          Name: node.parent.data.label
        }
      } else if (node.level === 2) {
        obj = {
          Name: item.label,
          DepartmentID: item.DepartmentID,
          DeviceUUID: item.DeviceUUID,
        }
      }
      this.choseNode = obj
      const data = {
        Paging: {
          QueryPageNo: this.pageNum,
          QueryPageLength: this.pageSize
        },
        Filter: {
          StartTime: this.searchform.timeRange?.[0] || '',
          EndTime: this.searchform.timeRange?.[1] || '',
          Descp: this.searchform?.Descp || '',
          DepartmentID: item.DepartmentID,
          ...obj
        }
      }
      const res = await connrequest('GetIMChatLog', data)
      res.Data = res.Data || []
      res.Data.map(item => {
        item.TransTime = parseTime(item.TransTime, '{y}-{m}-{d} {h}:{i}:{s}')
      })
      this.tableData = res.Data
      this.total = res.Paging.TotalCount
      this.MessagesList = [...this.MessagesList, ...res.Data]
      this.MessagesList.sort(function (a, b) {
        return new Date(a.TransTime).getTime() - new Date(b.TransTime).getTime();
      });
      if (this.mode === 'chat') {
        this.$nextTick(() => {
          this.$refs.chatMessages.scrollTo({ top: this.$refs.chatMessages.scrollHeight, behavior: 'smooth' })
        })
      }
      this.tabClick({ label: this.tabTitle || '按日统计分析' })
    },
    changeMode(mode) {
      this.mode = mode
      // this.deleteClick = false
      this.$nextTick(() => {
        this.$refs.chatMessages.scrollTo({ top: this.$refs.chatMessages.scrollHeight, behavior: 'smooth' })
      })
    },
    level5Click(tab) {
      this.ChatTabTitle = tab.label
      this.pageNum = 1
      if (tab.label === '看板模式') {
        this.$nextTick(() => {
          this.$refs.chatMessages.scrollTo({ top: this.$refs.chatMessages.scrollHeight, behavior: 'smooth' })
        })
      }
      if (tab.label === '列表模式') {
        this.$nextTick(() => {
          this.GetIMChatLog()
        })
      }
    },
    compare(p) { //这是比较函数
      return function (m, n) {
        var a = m[p];
        var b = n[p];
        return b - a; //升序
      }
    },
    handleScroll() {
      // 获取标div相对视位置信息
      const rect = this.$refs.chatMessages.scrollTop;
      // 判断标是否在视口顶
      if (rect <= 0) {
        //调用接口
        // this.throttledCallApi();
        this.seeMore = true
      }
    },
    callApi() {
      // 在里写调用接口的逻辑
      this.pageNum++
      this.GetIMChatLog()
    },
    debounce(func, delay) {
      let timerId;
      return function (...args) {
        clearTimeout(timerId);
        timerId = setTimeout(() => {
          func.apply(this, args);
        }, delay);
      };
    },
    echartsClick(val, title, id, data) {
      this.pageNum = 1
      if (title === '按日统计分析') {
        this.searchobj = { StartTime: `${val} 00:00:00`, EndTime: `${val} 23:59:59` }
        this.GetIMChatLog(this.searchobj)
      } else if (title === '按资产统计分析') {
        this.searchobj = { DeviceUUID: this.devices.find(item => item.DeviceName === val)?.DeviceUUID  }
        this.GetIMChatLog(this.searchobj)
      } else if (title === '按聊天工具分类统计') {
        this.searchobj = { IMTool: val }
        this.GetIMChatLog(this.searchobj)
      } else if (title === '按聊天对象分类统计') {
        this.searchobj = { MsgSubType: data.ChatType, Account: data.Account, DeviceUUID: this.devices.find(item => item.DeviceName === data.DeviceName)?.DeviceUUID }
        this.GetIMChatLog(this.searchobj)
      }
    },
    generateTree(arr) {
      const generateRandomId = () => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(36); // 生成默认的随机ID
      const tree = [];
      arr.forEach(item => {
        let parentNode = this.findNode(tree, item.Department);
        if (!parentNode) {
          parentNode = {
            id: generateRandomId(),
            label: item.Department,
            DepartmentID: item.DepartmentID,
            DeviceUUID: item.DeviceUUID,
            Count: item.Count,
            children: []
          };
          tree.push(parentNode);
        }
        let childNode = this.findNode(parentNode.children, item.DeviceName);
        if (!childNode) {
          childNode = {
            id: generateRandomId(),
            label: item.DeviceName,
            DepartmentID: item.DepartmentID,
            DeviceUUID: item.DeviceUUID,
            Count: item.Count,
            children: []
          };
          parentNode.children.push(childNode);
        }
        let grandchildNode = this.findNode(childNode.children, item.IMTool);
        if (!grandchildNode) {
          grandchildNode = {
            id: generateRandomId(),
            label: item.IMTool,
            Count: item.Count,
            DepartmentID: item.DepartmentID,
            DeviceUUID: item.DeviceUUID,
            children: []
          };
          childNode.children.push(grandchildNode);
        }
        let greatGrandchildNode = this.findNode(grandchildNode.children, item.ChatType);
        if (!greatGrandchildNode) {
          greatGrandchildNode = {
            id: generateRandomId(),
            label: item.ChatType,
            Count: item.Count,
            DepartmentID: item.DepartmentID,
            DeviceUUID: item.DeviceUUID,
            children: []
          };
          grandchildNode.children.push(greatGrandchildNode);
        }
        let leafNode = {
          id: generateRandomId(),
          label: item.Account,
          DepartmentID: item.DepartmentID,
          DeviceUUID: item.DeviceUUID,
          Count: item.Count
        };
        greatGrandchildNode.children.push(leafNode);
      });
      return tree;
    },
    findNode(arr, label) {
      return arr.find(node => node.label === label);
    },
    transformArray(arr) {
      const result = [];
      for (const key in arr) {
        const obj = {};
        obj.label = key;
        if (typeof arr[key] === 'object' && Object.keys(arr[key])?.length > 0) {
          obj.children = this.transformArray(arr[key]);
        }
        result.push(obj);
      }
      return result;
    },
    async organizationStructure() {
      const data = {
        Filter: {
          StartTime: this.searchform.timeRange?.[0] || '',
          EndTime: this.searchform.timeRange?.[1] || '',
          Descp: this.searchform?.Descp || '',
        }
      }
      const res = await connrequest('GetIMChatSumByAccount', data)
      // 构建树形结构
      const tree = {};
      res.Data = res.Data || []
      res.Data.map(item => {
        if (item.IMTool === 'WX') {
          item.ChatType = item.ChatType === 'Buddy' ? '私聊' : item.ChatType === 'Group' ? '群聊' : '公众号'
        }
        if (item.IMTool === 'QQ') {
          item.ChatType = item.ChatType === 'Buddy' ? '私聊' : item.ChatType === 'Group' ? '群聊' : '讨论组'
        }
      })
      // this.CustomerList = this.transformArray(this.generateTree(res.Data))
      this.CustomerList = this.generateTree(res.Data)
      if (this.CustomerList?.length > 0) {
        this.defaultDeployment = [this.CustomerList[0].id]
      }
    },
    addLevel(nodes, level = 1) {
      nodes.forEach(node => {
        node.level = level;
        if (node.children) {
          addLevel(node.children, level + 1);
        }
      });
    },
    // 获取事件日期统计
    async GetIMChatSumByDate() {
      let xAxis = []
      let series = []
      const data = {
        Filter: {
          StartTime: this.searchform.timeRange?.[0] || '',
          EndTime: this.searchform.timeRange?.[1] || '',
          Descp: this.searchform?.Descp || '',
          SumCount: 10,
          ...this.choseNode
        }
      }
      const res = await connrequest('GetIMChatSumByDate', data)
      res.Data = res.Data || []
      res.Data.map(item => {
        xAxis.push(item.Name)
        series.push(item.Count)
      })
      this.barchartData = { xAxis, series }
    },
    async GetIMChatSumByUser() {
      let arr = []
      const data = {
        Filter: {
          StartTime: this.searchform.timeRange?.[0] || '',
          EndTime: this.searchform.timeRange?.[1] || '',
          IMTool: this.searchform.IMTool || '',
          Name: this.searchform.Name || '',
          Descp: this.searchform?.Descp || '',
          SumCount: 10,
          ...this.choseNode
        }
      }
      const res = await connrequest('GetIMChatSumByUser', data)
      res.Data = res.Data || []
      res.Data.map(item => {
        arr.push({ name: item.Name, value: item.Count })
      })
      this.pie1Data = arr
    },
    // 聊天工具分类
    async GetIMChatSumByIMTool() {
      let arr = []
      const data = {
        Filter: {
          StartTime: this.searchform.timeRange?.[0] || '',
          EndTime: this.searchform.timeRange?.[1] || '',
          // IMTool: this.searchform.IMTool || '',
          // Name:this.searchform.Name || '',
          Descp: this.searchform?.Descp || '',
          SumCount: 10,
          ...this.choseNode
        }
      }
      const res = await connrequest('GetIMChatSumByIMTool', data)
      res.Data = res.Data || []
      res.Data.map(item => {
        arr.push({ name: item.Name, value: item.Count, id: item.ClassID })
      })
      this.pie2Data = arr
    },
    // 聊天对象分类
    async GetIMChatSumByAccount() {
      let arr = []
      const data = {
        Filter: {
          StartTime: this.searchform.timeRange?.[0] || '',
          EndTime: this.searchform.timeRange?.[1] || '',
          IMTool: this.searchform.IMTool || '',
          Name: this.searchform.Name || '',
          Descp: this.searchform?.Descp || '',
          SumCount: 10,
          ...this.choseNode
        }
      }
      const res = await connrequest('GetIMChatSumByAccount', data)
      res.Data = res.Data || []
      res.Data.map(item => {
        arr.push({ name: `${item.Account}(${item.ChatType === 'Buddy' ? '私聊' : '群聊'})`, value: item.Count, id: item.ClassID, ChatType: item.ChatType, Account: item.Account, DeviceName: item.DeviceName})
      })
      this.pie3Data = arr
    },
    // 获取聊天备份列表
    async GetIMChatLog(searchobj = {}) {
      const data = {
        Paging: {
          QueryPageNo: this.pageNum,
          QueryPageLength: this.pageSize
        },
        Filter: {
          StartTime: this.searchform.timeRange?.[0] || '',
          EndTime: this.searchform.timeRange?.[1] || '',
          Descp: this.searchform?.Descp || '',
          ...this.choseNode,
          ...searchobj
        }
      }
      const res = await connrequest('GetIMChatLog', data)
      res.Data = res.Data || []
      res.Data.map(item => {
        item.TransTime = parseTime(item.TransTime, '{y}-{m}-{d} {h}:{i}:{s}')
      })
      if (this.ChatTabTitle === '列表模式') {
        this.tableData = res.Data
      } else {
        this.MessagesList = [...this.MessagesList, ...res.Data]
        this.MessagesList.sort(function (a, b) {
          return new Date(a.TransTime).getTime() - new Date(b.TransTime).getTime();
        });
        if (this.pageNum > 1 && res.Data?.length > 0) {
          let scrollHeight = this.$refs.chatMessages.scrollHeight;
          this.$nextTick(() => {
            this.$refs.chatMessages.scrollTop = this.$refs.chatMessages.scrollHeight - scrollHeight
          });
        }
        if (Math.ceil(res.Paging.TotalCount / this.pageSize) < this.pageNum) {
          this.islast = true
        }
      }
      this.total = res.Paging.TotalCount
    },
    handleSizeChange(val) {
      this.pageNum = 1
      this.pageSize = val
      this.GetIMChatLog(this.searchobj)
    },
    handleCurrentChange(pageNum) {
      this.pageNum = pageNum
      this.GetIMChatLog(this.searchobj)
    },
    search(val) {
      this.pageNum = 1
      this.searchform = { ...val }
      if (this.searchform.timeRange) {
        if (this.searchform.timeRange) {
          this.searchobj = { StartTime: this.searchform?.timeRange[0] || '', EndTime: this.searchform?.timeRange[1] || '' }
        }
      }
      this.organizationStructure()
      this.getData()
    },
    reset() {
      let endTime = new Date(new Date().setHours(0, 0, 0, 0)).getTime()
      let startTime = endTime - ((Cookies.get('Zhuoguan_DefaultLogDays') || 7) * 24 * 3600 * 1000);
      let arr = [parseTime(startTime), '']
      this.pageNum = 1
      this.formOptions = this.formOptions.map(item => {
        if (item.label === "日期") {
          item.initValue = arr
        } else {
          item.initValue = ""
        }
        return item
      })
      this.searchform = {}
      this.$set(this.searchform, 'timeRange', arr)
      this.$refs.connsearch.addInitValue()
      this.organizationStructure()
      this.getData()
    },
    handleClick() {
      this.tab = !this.tab
    },
    handleClick2() {
      this.tab1 = !this.tab1
    },
  }
};
</script>
<style lang="scss" scoped>
@import "~@/styles/variables.scss";
@import "./components/css/conncss.scss";

.zoom-div {
  transition: transform 0.3s ease-in-out;
}

.zoom {
  position: fixed;
  right: 50px;
  bottom: 40px;
  font-size: 30px;
  z-index: 999999;
  color: #459ffc;
  cursor: pointer;
}

/* 设置垂直滚动条（如果需要水平滚动条，请添加::-webkit-scrollbar-horizontal选择器） */
::-webkit-scrollbar {
  width: 3px;
  /* 滚动条宽度 */
}

/* 滚动条轨道部分（即背景） */
::-webkit-scrollbar-track {
  background-color: #fff;
  /* 背景颜色 */
}

/* 滚动条上下两端的按钮 */
::-webkit-scrollbar-button {
  display: none;
  /* 隐藏按钮 */
}

/* 滚动条滑块部分（即滑块本身） */
::-webkit-scrollbar-thumb {
  background-color: #ccc;
  /* 滑块颜色 */
}

.tab {
  background: #f5f7fa;
}

.tabButton {
  cursor: pointer;
  font-size: 14px;
  padding: 10px;
  display: inline-block;
  text-align: center;
  color: #909399;
}

.tabButtonActive {
  color: #2491fc;
  background: #fff;
  border-left: 1px solid #dfe6ec;
  border-right: 1px solid #dfe6ec;
  border-bottom: 1px solid #fff;
  box-shadow: 0px 0px;
  // border: 1px solid #2491fc;
}

// .tabButton:hover{
//   background: #459ffc;
//   color: #fff;
// }
.chat-messages {
  height: calc(100vh - 320px);
  overflow-y: auto;
  font-size: 14px;
  line-height: 25px;
  display: flex;
  flex-direction: column;
  // background: #f5f5f5;
  background: #fff;
  padding: 15px;
  padding-top: 0;
}

.chat-avatar {
  padding-top: 10px;

  img {
    width: 35px;
    border-radius: 50%;
  }
}

.chat-content {
  display: flex;
  flex-direction: column;
}

pre {
  width: 50vw;
  // background-color: #f4f6f8;
  padding: 10px;
  border-radius: 10px;
}

code {
  width: 100%;
}

.chat-message-left {
  display: flex;
  border-radius: 5px;
  margin: 10px 0;
  align-self: flex-start;
  max-width: 500px;

  .chat-message-text {
    align-self: flex-start;
    margin-left: 10px;
    border-radius: 5px;
    padding: 10px;
    background-color: #fff;
    max-width: 800px;
    overflow: hidden;
  }

  .chat-time {
    align-self: flex-start;
    font-size: 12px;
    padding-left: 10px;
  }
}

.chat-message-right {
  display: flex;
  max-width: 500px;
  border-radius: 5px;
  margin: 10px 0;
  align-self: flex-end;

  .chat-message-text {
    align-self: flex-end;
    margin-right: 10px;
    border-radius: 5px;
    padding: 10px;
    background-color: #89d961;
  }

  .chat-time {
    font-size: 12px;
    color: #ccc;
    padding-right: 10px;
    align-self: flex-end;
  }
}

.lefttree {
  width: 280px;
  border: 1px solid #ebeef5;
  margin-right: 10px;
  padding: 10px;
  position: relative;
  overflow-y: auto;

  .tabclick {
    transform: rotate(-90deg);
    position: absolute;
    top: calc((100vh - 300px) / 2);
    left: -45px;
    margin-top: 20px;
  }

  .el-tree {
    color: #676c70;
    background-color: #ffffff;

    .tree-text {
      font-size: 14px;
      display: inline-block;
      width: 140px;
      white-space: nowrap;
      /* 禁止换行 */
      overflow: hidden;
      /* 溢出隐藏 */
      text-overflow: ellipsis;
      /* 超出部分用省略号表示 */
    }
  }


  ::v-deep .el-tree-node__content {
    &:hover {
      background-color: #f5f7fa;
    }
  }

  ::v-deep .el-tree-node.is-current>.el-tree-node__content {
    color: #459ffc !important;
    background-color: #f7f7f7 !important;
  }

  ::v-deep .el-tree-node__content{
    height: 36px !important;
  }

  // ::v-deep .el-tree-node__expand-icon{
  //   position :absolute;
  //   left: 2%;
  // }
  ::v-deep .el-tree-node__label {
    padding-left: 15px;
  }

}

.content {
  position: relative;
  margin-top: 25px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;

  ::v-deep .certification {
    .el-form-item {
      margin-bottom: 10px;
    }

    .el-col {
      display: flex;
      align-items: center;

      p {
        width: 100px;
        display: block;
        color: #aaa;
        font-size: 12px;
        padding-left: 20px;
        white-space: nowrap;
      }
    }
  }
}



::v-deep .el-tabs__content {
  padding: 0 !important;
}
.showOverflowTooltip {
  overflow: hidden !important;
  white-space: nowrap !important;
  text-overflow: ellipsis !important;
}
</style>